package Model;

import java.util.ArrayList;

import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.event.TreeModelListener;
import javax.swing.table.TableModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

import Controller.CtrlListeUtilisateur;
import Controller.CtrlSuppressionUtilisateur;
import Interface.IListeUtilisateur;

public class ListeUtilisateur implements IListeUtilisateur, TableModel, TreeModel {
	private java.util.List<Utilisateur> ListeUtilisateurs;
	private ArrayList<String> ColumnName;
	private ArrayList<TableModelListener> ListeModelListener;
	private ArrayList<CtrlSuppressionUtilisateur> ListeCtrlSuppListener;
	private ArrayList<CtrlListeUtilisateur> ListeCtrlListListener;
	private ArrayList<TreeModelListener> ListeTreeModelListener;
	
	public ListeUtilisateur() {
		ListeUtilisateurs = new ArrayList<Utilisateur>();
		ListeModelListener = new ArrayList<TableModelListener>();
		ListeCtrlSuppListener = new ArrayList<CtrlSuppressionUtilisateur>();
		ListeCtrlListListener = new ArrayList<CtrlListeUtilisateur>();
		ListeTreeModelListener = new ArrayList<TreeModelListener>();
		
		ColumnName = new ArrayList<String>();
		ColumnName.add("Login");
		ColumnName.add("Nom");
		ColumnName.add("Privilège");
		ColumnName.add("Supérieur");
	}

	@Override
	public void ajouterUtiliseur(Utilisateur u) {
		ListeUtilisateurs.add(u);
		fireTableRowsInserted(ListeUtilisateurs.size(), ListeUtilisateurs.size());
	}

	@Override
	public void ajouterUtilisateur(String nom, String login, String password, Privilege privilege, String loginSuperieur) {
		ajouterUtiliseur(new Utilisateur(nom, login, password, privilege, loginSuperieur));
	}

	@Override
	public Utilisateur obtenirUtilisateur(int numeroLigne) {
		return ListeUtilisateurs.get(numeroLigne);
	}

	@Override
	public void supprimerUtilisateur(int numeroLigne) {
		ListeUtilisateurs.remove(numeroLigne);
		fireTableRowsDeleted(numeroLigne, numeroLigne);
	}

	@Override
	public int obtenirNumeroLigneUtilisateur(String login) {
		for(int i = 0; i < ListeUtilisateurs.size(); i++) 
			if(ListeUtilisateurs.get(i).getLogin().equals(login)) return i;
			
		return -1;
	}

	@Override
	public void modifierUtilisateur(int ligne, Utilisateur u) {
		ListeUtilisateurs.set(ligne, u);
		fireTableRowsUpdated(ligne, ligne);
	}

	@Override
	public boolean verifierIdentite(String login, String password) {
		int index = obtenirNumeroLigneUtilisateur(login);
		
		if(index >= 0)
			return obtenirUtilisateur(index).checkPassword(password);
		else
			return false;
	}

	@Override
	public int nbUtilisateurs() {
		return ListeUtilisateurs.size();
	}

	@Override
	public int getRowCount() {
		return ListeUtilisateurs.size();
	}

	@Override
	public int getColumnCount() {
		return ColumnName.size();
	}

	@Override
	public String getColumnName(int columnIndex) {
		return ColumnName.get(columnIndex);
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		String colum = ColumnName.get(columnIndex);
		
		if(colum.equals("Login"))
			return ListeUtilisateurs.get(rowIndex).getLogin();
		else if(colum.equals("Nom"))
			return ListeUtilisateurs.get(rowIndex).getNom();
		else if(colum.equals("Privilège"))
			return ListeUtilisateurs.get(rowIndex).getNiveauPrivilege();
		else if(colum.equals("Supérieur"))
			return ListeUtilisateurs.get(rowIndex).getLoginSuperieurHierarchique();
		else
			return "A implémenter";
	}

	@Override
	public void setValueAt(Object value, int rowIndex, int columnIndex) {
		String colum = ColumnName.get(columnIndex);
		
		if(colum.equals("Login"))
			ListeUtilisateurs.get(rowIndex).setLogin((String) value);
		else if(colum.equals("Nom"))
			ListeUtilisateurs.get(rowIndex).setNom((String) value);
		else if(colum.equals("Privilège"))
			ListeUtilisateurs.get(rowIndex).setNiveauPrivilege((Privilege) value);
		else if(colum.equals("Supérieur"))
			ListeUtilisateurs.get(rowIndex).setLoginSuperieurHierarchique((String) value);
		
		fireTableCellUpdated(rowIndex, columnIndex);
	}
	
	@Override
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		return true;
	}

	@Override
	public Class<?> getColumnClass(int columnIndex) {
		return String.class;
	}

	@Override
	public void addTableModelListener(TableModelListener l) {
		ListeModelListener.add(l);
	}

	@Override
	public void removeTableModelListener(TableModelListener l) {
		ListeModelListener.remove(l);
	}
	
	public void fireTableRowsInserted(int a, int b) {
		updateTableListener(new TableModelEvent(this, a, b, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
		updateDeleteListener();
		updateListeListener();
	}
	
	public void fireTableRowsUpdated(int a, int b) {
		updateTableListener(new TableModelEvent(this, a, b));
		updateDeleteListener();
		updateListeListener();
	}

	public void fireTableCellUpdated(int a, int b) {
		updateTableListener(new TableModelEvent(this, a, a, b));
		updateDeleteListener();
		updateListeListener();
	}
	
	public void fireTableRowsDeleted(int a, int b) {
		updateTableListener(new TableModelEvent(this, a, b, TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE));
		updateDeleteListener();
		updateListeListener();
	}
	
	
	// http://download.oracle.com/javase/1.4.2/docs/api/javax/swing/event/TableModelEvent.html
	private void updateTableListener(TableModelEvent e) {
		for(int i = 0; i < ListeModelListener.size(); i++)
			ListeModelListener.get(i).tableChanged(e);
	}
	
	public void addDeleteUserListener(CtrlSuppressionUtilisateur ctrl) {
		ListeCtrlSuppListener.add(ctrl);
	}
	
	public void removeDeleteUserListener(CtrlSuppressionUtilisateur ctrl) {
		ListeCtrlSuppListener.remove(ctrl);
	}
	
	private void updateDeleteListener() {
		for(int i = 0; i < ListeCtrlSuppListener.size(); i++)
			ListeCtrlSuppListener.get(i).update();
	}
	
	public void addListeUserListener(CtrlListeUtilisateur ctrl) {
		ListeCtrlListListener.add(ctrl);
	}
	
	public void removeListeUserListener(CtrlListeUtilisateur ctrl) {
		ListeCtrlListListener.remove(ctrl);
	}
	
	private void updateListeListener() {
		for(int i = 0; i < ListeCtrlListListener.size(); i++)
			ListeCtrlListListener.get(i).update();
	}

	@Override
	public void addTreeModelListener(TreeModelListener l) {
		ListeTreeModelListener.add(l);
	}

	@Override
	public Object getChild(Object parent, int index) {
		int count = 0;
		String loginParent = (String)parent;
		
		for(int i=0; i < nbUtilisateurs(); i++) {
			if(ListeUtilisateurs.get(i).getLoginSuperieurHierarchique().equals(loginParent)) {
				if(count == index)
					return ListeUtilisateurs.get(i).getLogin();
				else
					count++;
			}
		}
		
		
		return null;
	}

	@Override
	public int getChildCount(Object parent) {
		int count = 0;
		String loginParent = (String)parent;
		
		for(int i=0; i < nbUtilisateurs(); i++) {
			if(ListeUtilisateurs.get(i).getLoginSuperieurHierarchique().equals(loginParent))
				count++;
		}
		return count;
	}

	@Override
	public int getIndexOfChild(Object parent, Object child) {
		int count = 0;
		String loginParent = (String)parent;
		
		for(int i = 0; i < nbUtilisateurs() && ListeUtilisateurs.get(i) != child; i++) {
			if(ListeUtilisateurs.get(i).getLoginSuperieurHierarchique().equals(loginParent))
				count++;
		}
		return count;
	}

	@Override
	public Object getRoot() {
		// TODO Auto-generated method stub
		return ListeUtilisateurs.get(0).getLogin();
	}

	@Override
	public boolean isLeaf(Object node) {
		return getChildCount(node) == 0;
	}

	@Override
	public void removeTreeModelListener(TreeModelListener l) {
		ListeTreeModelListener.remove(l);
	}

	@Override
	public void valueForPathChanged(TreePath path, Object newValue) {
		// TODO Auto-generated method stub
		
	}
}
